<?php
/* [DoYouHaoBaby!] (C)Dianniu From 2010.
   计时器($)*/

!defined('DYHB_PATH')&& exit;

class Timer{

	private $_nMicroSec=0;
	private $_oCallback;
	private $_arrArgs;
	private $_nStateTime;
	private $_nDoCount=0;
	private $_nDoneCount=0;
	private $_bDoing=false;
	private $_nTimerId=-1;
	private $_bAutoDestroy=false;
	static private $_arrTimers=array();
	static private $_nAssignTimerId=0;

	public function __construct($nSec,$nMicroSec=0,$bAutoDestroy=false){
		A::INT($nSec);
		A::INT($nMicroSec); 
		$this->_nMicroSec=$nSec+($nMicroSec/1000);
		$this->_bAutoDestroy=$bAutoDestroy;
		$this->_nTimerId=self::$_nAssignTimerId++;
		self::$_arrTimers[$this->_nTimerId]=$this;
	}

	static public function createTimerIterator(){
		return new DArrayIterator(self::$_arrTimers);
	}

	public function getTimerId(){
		return $this->_nTimerId;
	}

	public function destroyTimer(Timer $oTimer){
		unset(self::$_arrTimers[$oTimer->getTimerId()]);
	}

	public function start($Callbace,$nDoCount=1,$arrArgs=array()){
		A::INT($nDoCount);
		A::ASSERT_($this->_bDoing===false,G::L('计时器已经开始，在结束前无法重复调用 start方法。','gtk'));
		$this->_oCallback=$Callbace;
		$this->_nStateTime=microtime(true);
		$this->_nDoCount=$nDoCount;
		$this->_nDoneCount=0;
		$this->_arrArgs=$arrArgs;
		$this->_bDoing=true;
	}

	public function isDoing(){
		return $this->_bDoing;
	}

	public function loopOnce(){
		if($this->_nDoCount===0){
			return;
		}
		if($this->isTimeOut()){
			$this->_nDoCount--;
			$this->_nDoneCount++;
			$this->_nStateTime=microtime(true);
			call_user_func_array($this->_oCallback,$this->_arrArgs);
			if($this->_nDoCount===0){// 结束
				$this->_bDoing=false;
				if($this->_bAutoDestroy){// 自动销毁
					self::destroyTimer($this);
				}
			}
		}
	}

	public function isTimeOut(){
		if(!$this->isDoing()){
			return false;
		}
		return(microtime(true)-$this->_nStateTime)>=$this->_nMicroSec;
	}

	static public function tick(){
		foreach(self::$_arrTimers as $oTimer){
			$oTimer->loopOnce();
		}
	}
	
}
